perf(entity): scope availability subscription to the lock entities#1306
Open
terafin wants to merge 1 commit into
Open
perf(entity): scope availability subscription to the lock entities#1306terafin wants to merge 1 commit into
terafin wants to merge 1 commit into
Conversation
The availability binary_sensor registered its state-change handler with
`async_track_state_change_filtered(hass, TrackStates(True, set(), set()), ...)`.
`all_states=True` subscribes to EVERY state change in the Home Assistant
instance; the handler then filters in Python and early-returns for any entity
that isn't one of the slot's locks.
On a production instance with ~6-7 of these entities, cProfile measured the
handler running ~86,580 times / 30s (~2,900/sec) and its inner generator
~640,100 times / 30s — the single largest application-level CPU consumer,
doing no useful work.
Scope the subscription to just the lock entities via
`TrackStates(False, {lock.lock.entity_id for lock in self.locks}, set())`.
Because `self.locks` is mutated at runtime by `_handle_add_locks` /
`_handle_remove_lock`, the tracked set is re-scoped with
`async_update_listeners` whenever locks change, and availability is recomputed
at that point (previously the all-states firehose recomputed it implicitly).
Pure performance fix; no behavior change. Adds a regression test asserting the
subscription is scoped to the locks and re-scopes on lock add/remove.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Proposed change
The availability
binary_sensorregisters its state-change handler withall_states=True:TrackStates(True, ...)subscribes to every state change in the entire Home Assistant instance._handle_available_state_updatethen filters in Python and early-returns for any entity that isn't one of the slot's locks.On a production instance with ~6–7 of these entities,
cProfilemeasured the handler running ~86,580 times / 30s (~2,900/sec) and its inner generator ~640,100 times / 30s — the single largest application-level CPU consumer, doing no useful work.Fix
Scope the subscription to just the lock entities:
self.locksis mutated at runtime (_handle_add_locks/_handle_remove_lock), so the tracked set is re-scoped viaasync_update_listeners()whenever locks change, and availability is recomputed at that point — previously the all-states firehose recomputed it implicitly, so this preserves behavior for the dynamic add/remove-lock case. The initial availability computation and theasync_on_removecleanup are unchanged.Pure performance fix; no behavior change. Verified: the full
test_binary_sensor.py,test_event.py, andtest_callbacks.pysuites pass (48 tests), and a new regression test asserts the subscription is scoped to the locks and re-scopes on lock add/remove.Type of change
Additional information
cProfileon a production HA instance running 4.2.0.🤖 Generated with Claude Code